package com.xiaouyudeguang.common.permit;

import com.xiaouyudeguang.common.annotation.ApiMapping;
import com.xiaouyudeguang.common.annotation.ApiResource;
import com.xiaouyudeguang.common.utils.RegularUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Pattern;

/**
 * <p>
 * Inner注解配置忽略路径
 * </p>
 *
 * @author zhaog
 * @version v1.0
 * @since 2020/12/30
 */
@Configuration
public class PermitUrlBean {

    private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}");

    @Autowired
    private WebApplicationContext applicationContext;

    public List<String> getIgnoreUrls() {
        List<String> ignoreUrls = new ArrayList<>();
        RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
        Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();

        map.keySet().forEach(info -> {
            HandlerMethod handlerMethod = map.get(info);
            // 获取方法上边的注解 替代path variable 为 *
            ApiMapping method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), ApiMapping.class);
            Optional.ofNullable(method)
                    .filter(ApiMapping::isOpen)
                    .ifPresent(it -> info.getPatternsCondition().getPatterns()
                            .forEach(url -> {
                                ignoreUrls.add(RegularUtils.replaceAll(url, PATTERN, "*"));
                            }));

            // 获取类上边的注解, 替代path variable 为 *
            ApiResource controller = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), ApiResource.class);
            Optional.ofNullable(controller)
                    .filter(ApiResource::isOpen)
                    .ifPresent(it -> info.getPatternsCondition().getPatterns()
                            .forEach(url -> ignoreUrls.add(RegularUtils.replaceAll(url, PATTERN, "*"))));
        });
        return ignoreUrls;
    }
}
